﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ViewMaker;
using System.Diagnostics;
using CloudStorageLight.Core;
using Ionic.Zip;
using System.Text;
using ViewMaker.Core;
using System.Collections.Generic;
using System.Windows;
using System.Runtime.Serialization.Formatters.Binary;
using iTextSharp.text.pdf;

namespace CloudStorageLight.WpfClient.Tests
{
    [TestClass]
    public class ScenarioTest
    {
 

        private string workFile;
        private string workFile2;
        private string workFile3;

        private SynchronizationContext SyncCtx = new SynchronizationContext();

        [TestInitialize]
        public void TestSetUp()
        {
            
            //SynchronizationContext.SetSynchronizationContext(SyncCtx);

            AppViewModel.ExecuteActionAsyncMode = false;
            AppViewModel.ProcessStartMode = false;

            BlobDataManager.Instance = new BlobDataManager();
            BlobDataManager.Instance.LoginAsync(AppUtil.GetAppConfigValue("ServerUrl"), AppUtil.GetAppConfigValue("User"), AppUtil.GetAppConfigValue("Password")).Wait();
            BlobDataManager.Instance.RestoreCachedFile();
            //BlobDataManager.Instance.RestoreFolderMapdFile();
            var setting = BlobDataManager.Instance.LoadSettings();
            BlobDataManager.Instance.SaveSettings(setting);
            var vm = new MyMainVM();
            vm.Init();

            
            //GetAndEnsureFolderTree(vm, "/UNITTEST/");
            //GetAndEnsureFolderTree(vm, "/LocalFile/TestSub/");
            //GetAndEnsureFolderTree(vm, "/SharePoint/TestSub/");

            //vm.DeleteFileCommand.Execute(new FileCommandArg() { Files = new string[] { "/UNITTEST/", "/LocalFile/TestSub/", "/SharePoint/TestSub/"} });
            //WaitIdle(vm).Wait();

            //try
            //{
            //    BlobDataManager.Instance.CreateFolderAsync("/", "UNITTEST").Wait();
            //}
            //catch { }
            //try
            //{
            //    BlobDataManager.Instance.CreateFolderAsync("/UNITTEST/", "SUB1").Wait();
            //}
            //catch { }
            //try
            //{
            //    BlobDataManager.Instance.CreateFolderAsync("/UNITTEST/", "SUB2").Wait();
            //}
            //catch { }
            //try
            //{
            //    BlobDataManager.Instance.CreateFolderAsync("/UNITTEST/", "SUB3").Wait();
            //}
            //catch { }
            //try
            //{
            //    BlobDataManager.Instance.CreateFolderAsync("/SharePoint/", "TestSub").Wait();
            //}
            //catch { }
            //try
            //{
            //    BlobDataManager.Instance.CreateFolderAsync("/LocalFile/", "TestSub").Wait();
            //}
            //catch { }
            workFile = "A.TXT";
            File.WriteAllText(workFile, "こんにちわ");
            workFile2 = "B.TXT";
            File.WriteAllText(workFile2, "こんにちわ");
            workFile3 = "ﾄﾞｷｭﾒﾝﾄ.txt";
            File.WriteAllText(workFile3, "テストデータABC" + DateTime.Now.ToString());
            BlobDataManager.Instance.UploadFileAsync("/UNITTEST/", workFile).Wait();
        }


        [TestCleanup]
        public void TestCleanup()
        {
            //File.Delete(workFile);
        }


        [TestMethod]
        public void Main起動()
        {
            var vm = new MyMainVM();
            vm.Init();
            Assert.IsTrue(vm.Folders.Count > 0);
        }


        private string[] testFolders = new string[] { "/FTP", "/DropBox", "/AzureBlob", "/SharePoint", "/Google" };
        private readonly object F;

        [TestMethod]
        public void Mainシナリオ()
        {
            var root = "/Main";
            CommonTest(root);
        }

        private void CommonTest(string root)
        {
            完全削除(root);
            フォルダコピー削除テスト(root);
            アクセス制御テスト(root);
            Vesrionテスト(root);
            パスコードテスト(root);
        }

        [TestMethod]
        public void FTPシナリオ()
        {
            var root = "/FTP";
            CommonTest(root);
        }

        [TestMethod]
        public void DropBoxシナリオ()
        {
            var root = "/DropBox";
            CommonTest(root);
        }

        [TestMethod]
        public void Googleシナリオ()
        {
            //var root = "/Google";
            //Vesrionテスト(root);
        }


        [TestMethod]
        public void SharePointシナリオ()
        {
            var root = "/SharePoint";
            完全削除(root);
            フォルダコピー削除テスト(root);
            アクセス制御テスト(root);
            Vesrionテスト(root);
            パスコードテストRMS(root);
        }

        private void 完全削除(string path)
        {
            path = path + "/";
            var vm = new MyMainVM();
            vm.Init();

            var data = new FileCommandArg();
            data.Files = new string[] { path };
            data.Path = null;
            data.Data["Completely"] = true;
            vm.DeleteFileCommand.Execute(data);
            if (IsDeleteFolderError(vm.Message)) vm.DeleteFileCommand.Execute(data);
            Assert.IsTrue(string.IsNullOrEmpty(vm.Message) || IsDeletePermitError(vm.Message));
            try
            {
                BlobDataManager.Instance.CreateFolderAsync("/", path.Trim('/')).Wait();
            }
            catch (Exception){ }
            BlobDataManager.Instance.SetProtectedMode(path, "None").Wait();

        }
        private bool IsPermitError(string msg)
        {
            var msg1 = "The operation has failed because it has not been permitted.";
            var msg2 = "許可されていないため操作が失敗しました";
            return msg == msg1 || msg == msg2;
        }

        private bool IsDeletePermitError(string msg)
        {
            var msg1 = "The folder is non deletable.";
            var msg2 = "このフォルダは削除できません";
            return msg == msg1 || msg == msg2;
        }
        
        private bool IsDeleteFolderError(string msg)
        {
            var msg1 = "Folders can not be deleted because it is not empty .";
            var msg2 = "フォルダが空でないため削除することができません。";
            return msg == msg1 || msg == msg2;
        }


        private bool IsCancelled(string msg)
        {
            var msg1 = "a request processing is cancelled";
            var msg2 = "キャンセルされました";
            return msg == msg1 || msg == msg2;
        }

        private bool IsOverwriteConfirmMessage(string msg)
        {
            var msg1 = "Do you overwrite the localfile by download file? ";
            var msg2 = "ダウンロードしたファイルでローカルファイルを上書きしてよろしいでしょうか？";
            return msg.Contains(msg1) || msg.Contains(msg2);
        }

        private void アクセス制御テスト(string path)
        {
            path = path + "/";
            try
            {
                var vm = new MyMainVM();
                vm.Init();

                var data = new FileCommandArg();
                data.Path = path;
                data.Files = new string[] { workFile };
                vm.UploadCommand.Execute(data);
                BlobDataManager.Instance.SetAccessControlAsync(path, "admin:rwmc,everyone:").Wait();
                ChangeUser2();

                var targetFolder =  GetAndEnsureFolderTree(vm, path);
                Assert.IsNull(targetFolder);

                ChangeUser1();
                BlobDataManager.Instance.SetAccessControlAsync(path, "admin:rwmc,everyone:r").Wait();
                ChangeUser2();

                targetFolder = GetAndEnsureFolderTree(vm, path);
                Assert.AreEqual(1, targetFolder.Files.Count);

                data = new FileCommandArg();
                data.Files = new string[] { path + "A.TXT" };
                data.Path = null;
                vm.DeleteFileCommand.Execute(data);
                Assert.IsTrue(IsPermitError(vm.Message));

                ChangeUser1();

                GetAndEnsureFolderTree(vm, path);
                vm.CurrentPath = path;
                vm.ShowDialogAction = (x) =>
                {
                    var dia = (DirectorySetupVM)x;
                    dia.SetAccessTokenString("admin:rwmc,everyone:rwm");
                    dia.Updated = true;
                };
                vm.ShowDirectorySetupCommand.Execute(null);
                Assert.AreEqual("", vm.Message);

                ChangeUser2();
                data = new FileCommandArg();
                data.Files = new string[] { path + "A.TXT" };
                data.Path = null;
                vm.DeleteFileCommand.Execute(data);
                Assert.AreEqual("", vm.Message);

            }
            finally
            {
                ChangeUser1();
                BlobDataManager.Instance.SetAccessControlAsync(path, "admin:rwmc").Wait();
            }
        }

        public void フォルダコピー削除テスト(string path)
        {
            var vm = new MyMainVM();
            vm.Init();

            Debug.WriteLine(path);

            var data = new FileCommandArg();
            data.Path = path + "/";
            data.Files = new string[] { "/TestData/" };
            vm.CopyCommand.Execute(data);
            if (IsCancelled(vm.Message)) vm.CopyCommand.Execute(data);
            if (IsCancelled(vm.Message)) vm.CopyCommand.Execute(data);
            Assert.AreEqual("", vm.Message); 

            var targetFolder = GetAndEnsureFolderTree(vm, path + "/TestData/");
            Assert.IsTrue(targetFolder.Folders.Any(x => x.Path == path + "/TestData/サブフォルダ/"));
            Assert.AreEqual(1, targetFolder.Folders.Count);
            Assert.AreEqual(4, targetFolder.Files.Count);

            BlobDataManager.Instance.CreateFolderAsync(path +"/", "複製").Wait();
           
            data = new FileCommandArg();
            data.Path = path + "/複製/";
            data.Files = new string[] { path + "/TestData/サブフォルダ/" };
            vm.CopyCommand.Execute(data);

            targetFolder = GetAndEnsureFolderTree(vm, path + "/複製/サブフォルダ/");
            Assert.IsTrue(targetFolder.Folders.Any(x => x.Path == path + "/複製/サブフォルダ/空フォルダ/"));
            Assert.AreEqual(1, targetFolder.Folders.Count);
            Assert.AreEqual(2, targetFolder.Files.Count);


            targetFolder = GetAndEnsureFolderTree(vm, path + "/複製/サブフォルダ/");
            var renameFile = targetFolder.Files.FirstOrDefault(x => x.Path == path + "/複製/サブフォルダ/テストデータ.pptx");
            renameFile.Title = "テストデータnew.pptx";
            vm.RenameFileCommand.Execute(renameFile);
            Assert.AreEqual("", vm.Message);
            var newfile = BlobDataManager.Instance.GetFileAsync(path + "/複製/サブフォルダ/テストデータnew.pptx").Result;
            Assert.AreEqual("テストデータnew.pptx", newfile.Title);

            targetFolder.OldTitle = targetFolder.Title;
            targetFolder.Title = "Newサブフォルダ";
            vm.RenameFolderCommand.Execute(targetFolder);
            Assert.AreEqual("", vm.Message);

            targetFolder = GetAndEnsureFolderTree(vm, path + "/複製/Newサブフォルダ/");
            Assert.IsTrue(targetFolder.Files.Any(x => x.Path == path + "/複製/Newサブフォルダ/テストデータnew.pptx"));

            vm.SelectedFolder = GetAndEnsureFolderTree(vm, path + "/TestData/");
            vm.DownloadFolderCommand.Execute(Environment.CurrentDirectory);

            data = new FileCommandArg();
            data.Files = new string[] { path + "/TestData/" };
            vm.DeleteFileCommand.Execute(data);
            if (IsCancelled(vm.Message)) vm.DeleteFileCommand.Execute(data);

            targetFolder = GetAndEnsureFolderTree(vm, path + "/TestData/");
            Assert.IsNull(targetFolder);

            data.Files = new string[] { path + "/複製/" };
            vm.DeleteFileCommand.Execute(data);
            if (IsCancelled(vm.Message)) vm.DeleteFileCommand.Execute(data);
            if (IsCancelled(vm.Message)) vm.DeleteFileCommand.Execute(data);

            targetFolder = GetAndEnsureFolderTree(vm, path + "/複製/");
            Assert.IsNull(targetFolder);

        }


        public void Vesrionテスト(string folder)
        {
            folder = folder + "/";
            BlobDataManager.Instance.SetBackupMode(folder, true).Wait();
            var path = folder + workFile;
            var path2 = path + ".bak";
            BlobDataManager.Instance.DeleteCompletelyAsync(path).Wait();
            BlobDataManager.Instance.DeleteCompletelyAsync(path2).Wait();
            var upFile = BlobDataManager.Instance.UploadFileAsync(folder, workFile).Result;
            Thread.Sleep(5000);
            File.WriteAllText(workFile, DateTime.Now.ToString());
            upFile = BlobDataManager.Instance.UploadFileAsync(folder, workFile).Result;
            Thread.Sleep(5000);
            File.WriteAllText(workFile, DateTime.Now.ToString());
            upFile = BlobDataManager.Instance.UploadFileAsync(folder, workFile).Result;
            Thread.Sleep(5000);
            var temp = Path.GetTempFileName();
            try
            {
                var list = BlobDataManager.Instance.GetVersion(path).Result;
                Assert.AreEqual(2, list.Count);
                var file1Info = BlobDataManager.Instance.DownloadAsync(path, temp, list[0]).Result;
                var file3Info = BlobDataManager.Instance.DownloadAsync(path, temp, list[1]).Result;

                // RENAME
                BlobDataManager.Instance.RenameAsync(path, path2).Wait();

                var list2 = BlobDataManager.Instance.GetVersion(path2).Result;
                Assert.AreEqual(2, list2.Count);
                var file2Info = BlobDataManager.Instance.DownloadAsync(path2, temp, list2[0]).Result;
                var file4Info = BlobDataManager.Instance.DownloadAsync(path2, temp, list2[1]).Result;
                Assert.AreEqual(file1Info.LastWriteTime, file2Info.LastWriteTime);
                Assert.AreEqual(file3Info.LastWriteTime, file4Info.LastWriteTime);

                //UPLOAD＆RENAME
                upFile = BlobDataManager.Instance.UploadFileAsync(folder, workFile).Result;
                try
                {
                    BlobDataManager.Instance.RenameAsync(path2, path).Wait();
                    Assert.Fail();
                }
                catch (Exception ex)
                {
                    Assert.AreEqual("既に存在します", ex.InnerException.Message);
                }
                BlobDataManager.Instance.DeleteAsync(path).Wait();
                Thread.Sleep(10000);
                BlobDataManager.Instance.RenameAsync(path2, path).Wait();
                list = BlobDataManager.Instance.GetVersion(path).Result;
                Assert.AreEqual(3, list.Count);

                BlobDataManager.Instance.SetBackupMode(folder, false).Wait();
                path = folder + workFile2;
                upFile = BlobDataManager.Instance.UploadFileAsync(folder, workFile2).Result;
                upFile = BlobDataManager.Instance.UploadFileAsync(folder, workFile2).Result;
                list = BlobDataManager.Instance.GetVersion(path).Result;
                Assert.AreEqual(0, list.Count);

            }
            finally
            {
                File.Delete(temp);

            }

        }

        public void パスコードテスト(string path)
        {
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, path.Trim('/'));
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception){ }
            }
            Directory.CreateDirectory(work);

            path = path + "/";
            BlobDataManager.Instance.SetProtectedMode(path, "Password").Wait();
            var data = new FileCommandArg();
            data.Files = new string[] { "/TestData/" };
            data.Path = path;
            vm.CopyCommand.Execute(data);

            BlobDataManager.Instance.SetFilePasscode(path, "Password1234").Wait();


            var current = GetAndEnsureFolderTree(vm, path + "/TestData/");
            vm.SelectedFolder = current;

            vm.DownloadFolderCommand.Execute(work);

            Assert.AreEqual("", vm.Message);

            MsOffCryptoUtil.Decrypto(Path.Combine(work, "TestData.xlsx"), "Password1234");
            MsOffCryptoUtil.Decrypto(Path.Combine(work, "テストデータ.pptx"), "Password1234");
            Unzip(Path.Combine(work, "ﾄﾞｷｭﾒﾝﾄ.txt.zip"), "Password1234", Path.Combine(work, "Work"));

        }

        public void パスコードテストRMS(string path)
        {
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, path.Trim('/'));
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            path = path + "/";
            var data = new FileCommandArg();
            data.Files = new string[] { "/TestData/" };
            data.Path = path;
            vm.CopyCommand.Execute(data);

            BlobDataManager.Instance.SetFilePasscode(path, "Password1234").Wait();


            var current = GetAndEnsureFolderTree(vm, path + "/TestData/");
            vm.SelectedFolder = current;

            vm.DownloadFolderCommand.Execute(work);

            Assert.AreEqual("", vm.Message);

            try
            {
                MsOffCryptoUtil.Decrypto(Path.Combine(work, "TestData.xlsx"), "Password1234");
                Assert.Fail();
            }
            catch{ }
            try
            {
                MsOffCryptoUtil.Decrypto(Path.Combine(work, "テストデータ.pptx"), "Password1234");
                Assert.Fail();
            }
            catch { }
            Unzip(Path.Combine(work, "ﾄﾞｷｭﾒﾝﾄ.txt.zip"), "Password1234", Path.Combine(work, "Work"));

        }

        private void Unzip(string temp, string passcode, string target)
        {
            using (var zip = new ZipFile(temp))
            {
                zip.Password = passcode;
                zip.ExtractAll(target);
            }
        }

        [TestMethod]
        public void 開くシナリオ()
        {
            var targetPath = "/TestData/";
            var vm = new MyMainVM();
            vm.ReturnValueAsShowYesNo = false;
            vm.Init();

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            var file = targetFolder.Files.Where(x => x.Path.EndsWith("TestData.xlsx")).First();
            vm.CancelCheckoutCommand.Execute(file);
            vm.ExecuteFileCommand.Execute(file);
            Assert.AreEqual("", vm.Message);

            var fi = new FileInfo(vm.LastProcessStartCmd);
            Assert.AreEqual(FileAttributes.ReadOnly, fi.Attributes & FileAttributes.ReadOnly);
        }

        [TestMethod]
        public void フォルダ作成()
        {
            var targetPath = "/Main/";
            var vm = new MyMainVM();
            vm.Init();

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);
            vm.SelectedFolder = targetFolder;

            //セットアップ
            try
            {
                vm.DeleteFileCommand.Execute(new FileCommandArg() { Files = new string[] { "/Main/TestDire/" } });
            }
            catch (Exception)
            {
            }

            //フォルダ名指定なし
            vm.ShowDialogAction = (x) => { vm.CreateDirectoryDialog.FolderName = null; vm.CreateDirectoryDialog.DialogResult = true; };
            vm.CreateFolderCommand.Execute(null);

            //フォルダ指定
            vm.ShowDialogAction = (x) => { vm.CreateDirectoryDialog.FolderName = "TestDire"; vm.CreateDirectoryDialog.DialogResult = true; };
            vm.CreateFolderCommand.Execute(null);
            Assert.AreEqual("", vm.Message);

            //フォルダ指定重複
            vm.ShowDialogAction = (x) => { vm.CreateDirectoryDialog.FolderName = "TestDire"; vm.CreateDirectoryDialog.DialogResult = true; };
            vm.CreateFolderCommand.Execute(null);
            Assert.AreEqual("既に存在します", vm.Message);

            //不正な名前
            vm.ShowDialogAction = (x) => { vm.CreateDirectoryDialog.FolderName = "/Main"; vm.CreateDirectoryDialog.DialogResult = true; };
            vm.CreateFolderCommand.Execute(null);
            Assert.AreEqual("不正なディレクトリパスです", vm.Message);
        }

        [TestMethod]
        public void 編集シナリオ()
        {
            var targetPath = "/TestData/";
            var vm = new MyMainVM();
            vm.Init();

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            var file = targetFolder.Files.Where(x => x.Path.EndsWith("TestData.xlsx")).First();
            vm.CancelCheckoutCommand.Execute(file);

            //チェックアウト&編集
            vm.CheckoutExecuteFileCommand.Execute(file);
            Assert.AreEqual("", vm.Message);
            var fi = new FileInfo(vm.LastProcessStartCmd);
            Assert.AreEqual((FileAttributes)0, fi.Attributes & FileAttributes.ReadOnly);

            //2回目の編集
            vm.ExecuteFileCommand.Execute(file);
            Assert.AreEqual("", vm.Message);
            fi = new FileInfo(vm.LastProcessStartCmd);
            Assert.AreEqual((FileAttributes)0, fi.Attributes & FileAttributes.ReadOnly);

            //チェックイン
            vm.CheckinCommand.Execute(file);
            Assert.AreEqual("", vm.Message);

        }

        [TestMethod]
        public void 編集シナリオ_途中DRAGDROP_名前変更()
        {
            var targetPath = "/UNITTEST/";
            var vm = new MyMainVM();
            vm.Init();

            var upArg = new FileCommandArg();
            upArg.Path = targetPath;
            upArg.Files = new string[] { Path.GetFullPath(workFile3) };
            vm.UploadCommand.Execute(upArg);
            Assert.AreEqual("", vm.Message);

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);
            var file = targetFolder.Files.Where(x => x.Path.EndsWith(workFile3)).First();

            vm.DeleteFileCommand.Execute(new FileCommandArg { Files = new string[] { "/UNITTEST/名前変更.txt" }});
            vm.CancelCheckoutCommand.Execute(file);

            //チェックアウト&編集
            vm.CheckoutExecuteFileCommand.Execute(file);
            Assert.AreEqual("", vm.Message);
            var fi = new FileInfo(vm.LastProcessStartCmd);
            Assert.AreEqual((FileAttributes)0, fi.Attributes & FileAttributes.ReadOnly);

            //編集ファイルを外部から更新してアップロード
            File.WriteAllText(workFile3, "テストデータABC" + DateTime.Now.ToString());
            vm.UploadCommand.Execute(upArg);
            Assert.AreEqual("", vm.Message);
            var cacheData = BlobDataManager.Instance.GetCachedFile(file);
            Assert.AreEqual(null, cacheData);
            vm.ExecuteFileCommand.Execute(file);

            //名前変更
            file.OldTitle = file.Title;
            file.Title = "名前変更.txt";
            vm.RenameFileCommand.Execute(file);
            Assert.AreEqual("", vm.Message);

            cacheData = BlobDataManager.Instance.GetCachedFile(file);
            Assert.AreEqual("/UNITTEST/名前変更.txt", file.Path);
            Assert.AreEqual("名前変更.txt", Path.GetFileName(cacheData.LocalPath));
            Assert.AreEqual(File.ReadAllText(cacheData.LocalPath), File.ReadAllText(workFile3));
            Assert.AreEqual(file.CheckoutUser, AppUtil.GetAppConfigValue("User"));

            //チェックイン
            vm.CheckinCommand.Execute(file);
            Assert.AreEqual("", vm.Message);

            //リロード
            vm.ReloadCommand.Execute(file);
            cacheData = BlobDataManager.Instance.GetCachedFile(file);
            Assert.AreEqual(File.ReadAllText(cacheData.LocalPath), File.ReadAllText(workFile3));
        }

        [TestMethod]
        public void 編集状態でのリロード()
        {
            var targetPath = "/TestData/";
            var vm = new MyMainVM();
            vm.Init();
            string lastMerssage = "";
            vm.ViewCommandNotified += (s, e) =>
                {
                    if (e.Command == "ShowMessage")
                    {
                        var para = ((ShowMessageViewCommandInfo)e.Parameter);
                        para.Result = true;
                        lastMerssage = para.Message; 
                    }
                };

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            var file = targetFolder.Files.Where(x => x.Path.EndsWith("TestData.xlsx")).First();
            vm.CancelCheckoutCommand.Execute(file);

            //チェックアウト&編集
            vm.CheckoutExecuteFileCommand.Execute(file);
            Assert.AreEqual("", vm.Message);
            var fi = new FileInfo(vm.LastProcessStartCmd);
            Assert.AreEqual((FileAttributes)0, fi.Attributes & FileAttributes.ReadOnly);

            var cacheData = BlobDataManager.Instance.GetCachedFile(file);
            var date = new FileInfo(cacheData.LocalPath).LastWriteTime;

            //再ロード
            vm.ReloadCommand.Execute(file);
            cacheData = BlobDataManager.Instance.GetCachedFile(file);
            var date2 = new FileInfo(cacheData.LocalPath).LastWriteTime;

            Assert.AreEqual("", lastMerssage);
            Assert.IsTrue(date == date2);

            //ファイル更新
            var date3 = DateTime.Now;
            new FileInfo(cacheData.LocalPath).LastWriteTime = date3;

            //再ロード
            vm.ReloadCommand.Execute(file);
            cacheData = BlobDataManager.Instance.GetCachedFile(file);
            var date4 = new FileInfo(cacheData.LocalPath).LastAccessTime;

            Assert.IsTrue(vm.ShownMessages.Any(x=>IsOverwriteConfirmMessage(x)));
            Assert.IsTrue(date2 < date4);
            Assert.IsTrue(date3 < date4);
        }


        [TestMethod]
        public void リロード()
        {
            var targetPath = "/TestData/";
            var vm = new MyMainVM();
            vm.Init();

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            var file = targetFolder.Files.Where(x => x.Path.EndsWith("テストデータ.pptx")).First();
            vm.ReloadCommand.Execute(file);
            var cacheData = BlobDataManager.Instance.GetCachedFile(file);

            var date = new FileInfo(cacheData.LocalPath).LastWriteTime;
            var cdate = new FileInfo(cacheData.LocalPath).CreationTime;
            var adate = new FileInfo(cacheData.LocalPath).LastAccessTime;

            //再ロード
            vm.ReloadCommand.Execute(file);
            cacheData = BlobDataManager.Instance.GetCachedFile(file);
            var date2 = new FileInfo(cacheData.LocalPath).LastWriteTime;
            var cdate2 = new FileInfo(cacheData.LocalPath).CreationTime;
            var adate2 = new FileInfo(cacheData.LocalPath).LastAccessTime;

            Assert.IsTrue(date == date2);
            Assert.IsTrue(cdate == cdate2);
            Assert.IsTrue(adate < adate2);
        }

        //[TestMethod]
        //public void 差分ダウンロード()
        //{
        //    var targetPath = "/TestData/";
        //    var vm = new MyMainVM();
        //    vm.Init();
        //    BlobDataManager.Instance.SetFilePasscode(targetPath, "").Wait();

        //    var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

        //    var file = targetFolder.Files.Where(x => x.Path.EndsWith("ﾄﾞｷｭﾒﾝﾄ.txt")).First();
        //    vm.CheckoutCommand.Execute(file);
        //    vm.ReloadCommand.Execute(file);

        //        var cacheData = BlobDataManager.Instance.GetCachedFile(file);
        //    var content = File.ReadAllText(cacheData.LocalPath);
        //    var newContent = content + DateTime.Now.ToString();
        //    var temp = "ﾄﾞｷｭﾒﾝﾄ.txt";

        //    try
        //    {
        //        File.WriteAllText(temp, newContent);
        //        BlobDataManager.Instance.UploadFileAsync(BlobDataManager.GetDirectoryPath(file.Path), temp).Wait();

        //        //差分ロード
        //        vm.DeltaDownloadCommand.Execute(file);
        //        Assert.AreEqual("", vm.Message);

        //        var content2 = File.ReadAllText(cacheData.LocalPath);

        //        Assert.IsTrue(newContent == content2);

        //    }
        //    finally
        //    {
        //        File.WriteAllText(temp, content);
        //        BlobDataManager.Instance.UploadFileAsync(BlobDataManager.GetDirectoryPath(file.Path), temp).Wait();
        //        vm.CancelCheckoutCommand.Execute(file);
        //    }
        //}

        //[TestMethod]
        //public void 差分アップロード()
        //{
        //    var targetPath = "/TestData/";
        //    var vm = new MyMainVM();
        //    vm.Init();
        //    BlobDataManager.Instance.SetFilePasscode(targetPath, "").Wait();

        //    var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

        //    var file = targetFolder.Files.Where(x => x.Path.EndsWith("ﾄﾞｷｭﾒﾝﾄ.txt")).First();
        //    vm.CheckoutCommand.Execute(file);
        //    vm.ReloadCommand.Execute(file);

        //    var cacheData = BlobDataManager.Instance.GetCachedFile(file);
        //    var content = File.ReadAllText(cacheData.LocalPath);
        //    var newContent = content + DateTime.Now.ToString();
           
        //    try
        //    {
        //        File.WriteAllText(cacheData.LocalPath, newContent);

        //        //差分ロード
        //        vm.DeltaUploadCommand.Execute(file);
        //        Assert.AreEqual("", vm.Message);

        //        vm.ReloadCommand.Execute(file);
        //        cacheData = BlobDataManager.Instance.GetCachedFile(file);
        //        var content2 = File.ReadAllText(cacheData.LocalPath);

        //        Assert.IsTrue(newContent == content2);

        //    }
        //    finally
        //    {
        //        vm.CancelCheckoutCommand.Execute(file);
        //    }
        //}

        [TestMethod]
        public void 最新ファイル取得()
        {
            var targetPath = "/TestData/";
            var vm = new MyMainVM();
            vm.Init();

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            var file = targetFolder.Files.Where(x => x.Path.EndsWith("テストデータ.zip")).First();
            vm.CheckoutCommand.Execute(file);
            vm.ReloadCommand.Execute(file);

            var acc = BlobDataManager.Instance.GetRecentAsync().Result;
            Assert.IsTrue(acc.Any(x => x.Path == "/TestData/テストデータ.zip"));
        }

        [TestMethod]
        public void 大文字小文字区別()
        {
            var targetPath = "/";
            var vm = new MyMainVM();
            vm.Init();
            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);
            vm.SelectedFolder = targetFolder;

            //フォルダ指定
            vm.ShowDialogAction = (x) => { vm.CreateDirectoryDialog.FolderName = "CaseSensitive"; };
            vm.CreateFolderCommand.Execute(null);

            //準備
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            BlobDataManager.Instance.SetCaseInsensitive(targetFolder.Path, false).Wait();
            vm.DeleteFileCommand.Execute(new FileCommandArg { Files = new string[] { targetFolder.Path + Path.GetFileName(workFile), targetFolder.Path + Path.GetFileName(workFile).ToLower(), targetFolder.Path + "B.TXT" } });
            BlobDataManager.Instance.UploadFileAsync(targetFolder.Path, workFile).Wait();
            BlobDataManager.Instance.RenameAsync(targetFolder.Path + Path.GetFileName(workFile), targetFolder.Path + Path.GetFileName(workFile).ToLower()).Wait();
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            Assert.AreEqual(1, targetFolder.Files.Count);

            //大文字小文字を区別しない状態でアップロード
            vm.UploadCommand.Execute(new FileCommandArg { Path = targetFolder.Path, Files = new string[] { workFile } });
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            Assert.AreEqual(2, targetFolder.Files.Count);

            vm.DeleteFileCommand.Execute(new FileCommandArg { Files = new string[] {targetFolder.Path + Path.GetFileName(workFile) } });
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            Assert.AreEqual(1, targetFolder.Files.Count);

            //大文字小文字を区別する状態でアップロード
            BlobDataManager.Instance.SetCaseInsensitive(targetFolder.Path, true).Wait();
            vm.UploadCommand.Execute(new FileCommandArg { Path = targetFolder.Path, Files = new string[] { workFile } });
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            Assert.AreEqual(1, targetFolder.Files.Count);

            //名前の変更は失敗する
            BlobDataManager.Instance.UploadFileAsync(targetFolder.Path, workFile2).Wait();
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            vm.SelectedFile = targetFolder.Files.FirstOrDefault(x => x.Title == "B.TXT");
            vm.SelectedFile.Title = "A.TXT";
            vm.RenameFileCommand.Execute(vm.SelectedFile);
            Assert.AreNotEqual("", vm.Message);
            vm.DeleteFileCommand.Execute(new FileCommandArg { Files = new string[] { targetFolder.Path + "B.TXT" } });

            //コピーは成功する。ただしファイルは１つ
            BlobDataManager.Instance.UploadFileAsync(targetPath, workFile).Wait();
            vm.CopyCommand.Execute(new FileCommandArg{ Path =  targetFolder.Path, Files = new string[]{ targetPath + "A.TXT" }});
            Assert.AreEqual("", vm.Message);
            targetFolder = GetAndEnsureFolderTree(vm, targetPath + "CaseSensitive/");
            Assert.AreEqual(1, targetFolder.Files.Count);
            Assert.AreEqual(targetFolder.Path + "a.txt", targetFolder.Files[0].Path);
        }


        [TestMethod]
        public void アクセス制御パターンテスト_管理者()
        {
            var vm = new MyMainVM();
            vm.Init();


            var targetPath = SetupAccessPatternFolder(vm);
            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            //管理者権限ユーザ
            var testUser = AppUtil.GetAppConfigValue("User");
            var testPass = AppUtil.GetAppConfigValue("Password");

            foreach (var f in targetFolder.Folders)
            {
                CheckAccess(testUser, testPass, f.Path, "list,download,rename,upload,delete,createfolder,setaccesscontrol".Split(','), true);
            }
        }

        private string SetupAccessPatternFolder(MyMainVM vm)
        {
            ChangeUser1();
            var workFolder = "AccessTest";
            var targetPath = "/" + workFolder + "/";
            var cmd = new FileCommandArg { Files = new string[] { targetPath } };
            cmd.Data["Completely"] = true;
            vm.DeleteFileCommand.Execute(cmd);
            BlobDataManager.Instance.CreateFolderAsync("/", workFolder).Wait();
            BlobDataManager.Instance.SetAccessControlAsync(targetPath, "everyone:").Wait();
            var user = AppUtil.GetAppConfigValue("User");

            Task.WaitAll(
            CreateTestFolder(targetPath, "user", AppUtil.GetAppConfigValue("User")),
            CreateTestFolder(targetPath, "user2", AppUtil.GetAppConfigValue("User2")),
            CreateTestFolder(targetPath, "user3", AppUtil.GetAppConfigValue("User3")),
            CreateTestFolder(targetPath, "users", "users"),
            CreateTestFolder(targetPath, "sales", "sales"),
            CreateTestFolder(targetPath, "everyone", "everyone"),
            CreateTestFolder(targetPath, "guest", "guest"));
            return targetPath;
        }

        [TestMethod]
        public void アクセス制御パターンテスト_グループ所属()
        {
            var vm = new MyMainVM();
            vm.Init();


            var targetPath = SetupAccessPatternFolder(vm);
            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            //sales所属
            var testUser = AppUtil.GetAppConfigValue("User2");
            var testPass = AppUtil.GetAppConfigValue("Password2");

            foreach (var f in targetFolder.Folders)
            {

                if (f.Title.IndexOf("user_") >= 0 || f.Title.IndexOf("user3_") >= 0 || f.Title.IndexOf("users_") >= 0 || f.Title.IndexOf("guest_") >= 0)
                {
                    CheckAccess(testUser, testPass, f.Path, new string[]{});
                }
                else
                {
                    var token = f.Title.Split('_')[1].ToLower();
                    var expected = "";
                    if (token.Contains('r')) expected += ",list,download";
                    if (token.Contains('w')) expected += ",upload,createfolder";
                    if (token.Contains('w') && token.Contains('m')) expected += ",delete";
                    if (token.Contains('w') && token.Contains('m') && token.Contains('r')) expected += ",rename";
                    if (token.Contains('c')) expected += ",setaccesscontrol";
                    CheckAccess(testUser, testPass,  f.Path, expected.Trim(',').Split(','));
                }
            }

        }

        [TestMethod]
        public void アクセス制御パターンテスト_ユーザロール指定()
        {
            var vm = new MyMainVM();
            vm.Init();


            var targetPath = SetupAccessPatternFolder(vm);
            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            //sales所属
            var testUser = AppUtil.GetAppConfigValue("User3");
            var testPass = AppUtil.GetAppConfigValue("Password3");

            foreach (var f in targetFolder.Folders)
            {

                if (f.Title.IndexOf("user_") >= 0 || f.Title.IndexOf("user2_") >= 0 || f.Title.IndexOf("sales_") >= 0 || f.Title.IndexOf("guest_") >= 0)
                {
                    CheckAccess(testUser, testPass, f.Path, new string[] { });
                }
                else
                {
                    var token = f.Title.Split('_')[1].ToLower();
                    var expected = "";
                    if (token.Contains('r')) expected += ",list,download";
                    if (token.Contains('w')) expected += ",upload,createfolder";
                    if (token.Contains('w') && token.Contains('m')) expected += ",delete";
                    if (token.Contains('w') && token.Contains('m') && token.Contains('r')) expected += ",rename";
                    if (token.Contains('c')) expected += ",setaccesscontrol";
                    CheckAccess(testUser, testPass, f.Path, expected.Trim(',').Split(','));
                }
            }

        }


        [TestMethod]
        public void アクセス制御パターンテスト_Ownerルール()
        {
            var vm = new MyMainVM();
            vm.Init();

            ChangeUser1();
            var targetPath = "/AccessTest/Owner/";

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);

            var cmd = new FileCommandArg { Files = new string[] { targetPath } };
            cmd.Data["Completely"] = true;
            vm.DeleteFileCommand.Execute(cmd);
            BlobDataManager.Instance.CreateFolderAsync("/AccessTest/","Owner" ).Wait();
            BlobDataManager.Instance.UploadFileAsync(targetPath, workFile).Wait();

            ChangeUser1Normal();

            BlobDataManager.Instance.SetAccessControlAsync(targetPath, "everyone:").Wait();
            var listResult = BlobDataManager.Instance.GetFilesAsync(targetPath, 0).Result;
            Assert.AreEqual(1, listResult.Count());

            BlobDataManager.Instance.SetAccessControlAsync(targetPath, "everyone:,owner:").Wait();
            var listResult2 = BlobDataManager.Instance.GetFilesAsync(targetPath, 0).Result;
            Assert.AreEqual(0, listResult2.Count());
        }


        private void CheckAccess(string testUser, string testPass, string testFolder, string[] expected, bool admin = false)
        {
            Trace.WriteLine(testUser +"/" + testPass + "/" + testFolder + "/" + string.Join(",", expected));

            BlobDataManager.Instance.LoginAsync(AppUtil.GetAppConfigValue("ServerUrl"), testUser, testPass, admin).Wait();

            var work1 = testFolder + workFile;
            var work2 = testFolder + workFile2;


            var tmp =  Path.GetTempFileName();
            try
            {
                var listResult = BlobDataManager.Instance.GetFilesAsync(testFolder, 0).Result;
                if (expected.Contains("list"))
                {
                    Assert.AreEqual(2, listResult.Count);
                }
                else
                {
                    Assert.AreEqual(0, listResult.Count);
                }

                var downloadResult = true;
                try
                {
                    BlobDataManager.Instance.DownloadAsync(work1, tmp, null, null).Wait();
                }
                catch (Exception)
                {
                    downloadResult = false;
                }
                Assert.AreEqual(expected.Contains("download"), downloadResult);

                var renameResult = true;
                try
                {
                    BlobDataManager.Instance.RenameAsync(work2, testFolder + "名前変更.txt").Wait();
                }
                catch (Exception)
                {
                    renameResult = false;
                }
                Assert.AreEqual(expected.Contains("rename"), renameResult);

                var uploadResult = true;
                try
                {
                    BlobDataManager.Instance.UploadFileAsync(testFolder, workFile3).Wait();
                }
                catch (Exception )
                {
                    uploadResult = false;
                }
                Assert.AreEqual(expected.Contains("upload"), uploadResult);

                var deleteResult = true;
                try
                {
                    BlobDataManager.Instance.DeleteAsync(work1).Wait();
                    BlobDataManager.Instance.DeleteCompletelyAsync(work1).Wait();
                }
                catch (Exception )
                {
                    deleteResult = false;
                }
                Assert.AreEqual(expected.Contains("delete"), deleteResult);

                var createFolderResult = true;
                try
                {
                    BlobDataManager.Instance.CreateFolderAsync(testFolder, "newFolder").Wait();
                }
                catch (Exception )
                {
                    createFolderResult = false;
                }
                Assert.AreEqual(expected.Contains("createfolder"), createFolderResult);

                var setAccessControlResult = true;
                try
                {
                    var token =BlobDataManager.Instance.GetAccessControlAsync(testFolder).Result;
                    BlobDataManager.Instance.SetAccessControlAsync(testFolder, token).Wait();
                }
                catch (Exception )
                {
                    setAccessControlResult = false;
                }
                Assert.AreEqual(expected.Contains("setaccesscontrol"), setAccessControlResult);

            }
            finally
            {
                File.Delete(tmp);
            }
        }

        private async Task CreateTestFolder(string targetPath, string prefix, string user)
        {
            var tasks = new List<Task>();

            var path1 = targetPath + prefix + "_RWMC/";
            var path2 = targetPath + prefix + "_RWM/";
            var path3 = targetPath + prefix + "_RW/";
            var path4 = targetPath + prefix + "_R/";
            var path5 = targetPath + prefix + "_W/";
            var path6 = targetPath + prefix + "_WM/";
            var path7 = targetPath + prefix + "_C/";

            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_RWMC"));
            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_RWM"));
            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_RW"));
            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_R"));
            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_W"));
            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_WM"));
            tasks.Add(BlobDataManager.Instance.CreateFolderAsync(targetPath, prefix + "_C"));
            Task.WaitAll(tasks.ToArray());
            tasks.Clear();


            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path1, user + ":rwmc"));
            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path2, user + ":rwm"));
            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path3, user + ":rw"));
            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path4, user + ":r"));
            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path5, user + ":w"));
            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path6, user + ":wm"));
            tasks.Add(BlobDataManager.Instance.SetAccessControlAsync(path7, user + ":c"));
            Task.WaitAll(tasks.ToArray());
            tasks.Clear();

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path1, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path1, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path1, AppUtil.GetAppConfigValue("User3")));

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path2, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path2, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path2, AppUtil.GetAppConfigValue("User3")));

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path3, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path3, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path3, AppUtil.GetAppConfigValue("User3")));

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path4, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path4, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path4, AppUtil.GetAppConfigValue("User3")));

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path5, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path5, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path5, AppUtil.GetAppConfigValue("User3")));

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path6, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path6, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path6, AppUtil.GetAppConfigValue("User3")));

            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path7, workFile));
            tasks.Add(BlobDataManager.Instance.UploadFileAsync(path7, workFile2));
            tasks.Add(BlobDataManager.Instance.SetUsersRole(path7, AppUtil.GetAppConfigValue("User3")));

            await Task.WhenAll(tasks.ToArray());
        }



        //[TestMethod]
        //public void ダウンロード日付()
        //{
        //    var targetPath = "/UNITTEST/";
        //    var vm = new MyMainVM();
        //    vm.Init();

        //    //アップロード
        //    var workFileDate1 = File.GetLastWriteTimeUtc(workFile3);
        //    BlobDataManager.Instance.UploadFileAsync(targetPath, workFile3).Wait();
        //    //BlobDataManager.Instance.FolderMappings.Add(new FolderMapItem { LocalFolder = Environment.CurrentDirectory, Path = targetPath });
        //    var cachePath = Path.Combine(BlobDataManager.Instance.GetMappingFolder(targetPath), Path.GetFileName(workFile3));

        //    //全てファイルをダウンロード
        //    var targetFolder = GetAndEnsureFolderTree(vm, targetPath);
        //    vm.SelectedFolder = targetFolder;
        //    vm.ReturnValueAsShowYesNo = false;
        //    vm.DownloadFolderCommand.Execute(null);

        //    //キャッシュファイル
        //    var workFileDate2 = File.GetLastWriteTimeUtc(cachePath);
        //    Assert.AreEqual(workFileDate1, workFileDate2);


        //    //キャッシュファイル更新
        //    File.WriteAllText(cachePath, "テストデータABC" + DateTime.Now.ToString());
        //    var workFileDate3 = File.GetLastWriteTimeUtc(cachePath);
        //    Assert.IsTrue(workFileDate2 < workFileDate3);

        //    //新しいファイルのみ更新
        //    vm.ReturnValueAsShowYesNo = true;
        //    vm.DownloadFolderCommand.Execute(null);
        //    var workFileDate4 = File.GetLastWriteTimeUtc(cachePath);
        //    Assert.AreEqual(workFileDate3, workFileDate4);

        //    //全てファイルをダウンロード
        //    vm.ReturnValueAsShowYesNo = false;
        //    vm.DownloadFolderCommand.Execute(null);
        //    var workFileDate5 = File.GetLastWriteTimeUtc(cachePath);
        //    Assert.AreEqual(workFileDate3, workFileDate4);


        //    vm.ReturnValueAsShowYesNo = false;
        //    vm.DownloadFolderCommand.Execute(null);

        //    var workFileDate6 = File.GetLastWriteTimeUtc(cachePath);
        //    Assert.AreEqual(workFileDate1, workFileDate6);

        //}





        private static void ChangeUser1()
        {
            BlobDataManager.Instance.LoginAsync(AppUtil.GetAppConfigValue("ServerUrl"), AppUtil.GetAppConfigValue("User"), AppUtil.GetAppConfigValue("Password"), true).Wait();
        }

        private static void ChangeUser1Normal()
        {
            BlobDataManager.Instance.LoginAsync(AppUtil.GetAppConfigValue("ServerUrl"), AppUtil.GetAppConfigValue("User"), AppUtil.GetAppConfigValue("Password"), false).Wait();
        }

        private static void ChangeUser2()
        {
            BlobDataManager.Instance.LoginAsync(AppUtil.GetAppConfigValue("ServerUrl"), AppUtil.GetAppConfigValue("User2"), AppUtil.GetAppConfigValue("Password2")).Wait();
        }


        private DirectoryItem GetAndEnsureFolderTree(MainVM vm, string path)
        {
            try
            {
                DirectoryItem target = vm.Folders[0];
                target.LoadChildrenAsync(true).Wait();

                var subPath = "/";

                foreach (var item in path.Split('/'))
                {
                    if (string.IsNullOrEmpty(item)) continue;
                    subPath = subPath + item + "/";
                    target = target.Folders.Where(x => x.Path == subPath).FirstOrDefault();
                    if (target == null) break;
                    target.LoadChildrenAsync(true).Wait();
                }
                return target;

            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex);
                return null;
            }
        }

        [TestMethod]
        public void カットペースト()
        {
            var targetPath = "/UNITTEST/";
            var vm = new MyMainVM();
            vm.Init();

            GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;
            vm.Files.Where(x => x.Title == "A.TXT").First().IsSelected = true;
            vm.FilesCutCommand.Execute(null);
            vm.FilesCopyCommand.Execute(null);
            GetAndEnsureFolderTree(vm , targetPath + "SUB1/");
            vm.CurrentPath = targetPath + "SUB1/";
            vm.FilesPasteCommand.Execute(null);
            vm.RefreshCommand.Execute(null);
            Assert.IsTrue(vm.Files.Any(x => x.Title == "A.TXT"));
            var fileObj = new OutlookDataObject(System.Windows.Clipboard.GetDataObject() as IDataObject);
            string[] filenames = (string[])fileObj.GetData(CloudStorageLight.WpfClient.VirtualFileDataObject.NativeMethods.CFSTR_FILEDESCRIPTORW);
            MemoryStream[] filestreams = (MemoryStream[])fileObj.GetData(CloudStorageLight.WpfClient.VirtualFileDataObject.NativeMethods.CFSTR_FILECONTENTS);

            var files = new System.Collections.Specialized.StringCollection();
            files.Add(workFile);
            files.Add(workFile2);
            Clipboard.SetFileDropList(files);
            vm.FilesPasteCommand.Execute(null);
            vm.RefreshCommand.Execute(null);
            Assert.IsTrue(vm.Files.Any(x => x.Title == "B.TXT"));

        }

        [TestMethod]
        public void フォルダアップロード()
        {
            var targetPath = "/Demo/Sub/";
            var vm = new MyMainVM();
            vm.Init();

            GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;
           
            vm.UploadFolderCommand.Execute(null);
        }

        [TestMethod]
        public void フォルダ保存()
        {
            var targetPath = "/Demo/Sub/";
            var vm = new MyMainVM();
            vm.Init();

            GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;

            vm.UploadFolderCommand.Execute(null);
        }


        [TestMethod]
        public void ファイル保存()
        {
            var targetPath = "/Demo/";
            var vm = new MyMainVM();
            vm.Init();

            var tempname = Path.Combine(Path.GetTempPath(), "A.TXT");
            if (File.Exists(tempname)) File.Delete(tempname);
            GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;
            vm.SelectedFile = vm.Files.Where(x => x.Title == "A.TXT").FirstOrDefault();
            vm.SelectedFile.IsSelected = true;
            vm.FilesSaveCommand.Execute(null);
            Assert.IsTrue(File.Exists(tempname));
        }


        [TestMethod]
        public void Path変更URL表示()
        {
            var targetPath = "/Demo/Sub/";
            var vm = new MyMainVM();
            vm.Init();
            vm.CurrentPath = "/";
            vm.SelectedItemChanged(vm.Folders[0]);

            var next = GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;
            vm.SelectedItemChanged(next);

            vm.PreviousPathChangeCommand.Execute(null);
            Assert.AreEqual("/", vm.SelectedFolder.Path);
            vm.ForwardPathChangeCommand.Execute(null);
            Assert.AreEqual("/Demo/Sub/", vm.SelectedFolder.Path);

            vm.SelectedFile = vm.Files.Where(x => x.Title == "A.TXT").FirstOrDefault();
            vm.ShowUrlCommand.Execute(null);
        }


        [TestMethod]
        public void オフライン()
        {
            try
            {
                BlobDataManager.Instance.Offline = true;

                var vm = new MyMainVM();
                vm.Init();
            }
            finally
            {

                BlobDataManager.Instance.Offline = false;
            }

        }

        [TestMethod]
        public void 検索キーワード()
        {
            var targetPath = "/Demo/";
            var vm = new MyMainVM();
            vm.Init();
            GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;
            vm.SearchText = "テスト";
            vm.SearchCommand.Execute(null);
            Assert.IsTrue(vm.Files.Count > 0);
        }

        [TestMethod]
        public void 最新()
        {
            var vm = new MyMainVM();
            vm.Init();
            vm.GetRecentCommand.Execute(null);
            Assert.IsTrue(vm.Files.Count > 0);
        }

        //[TestMethod]
        //public void 全同期()
        //{
        //    var vm = new MyMainVM();
        //    vm.Init();
        //    vm.AllFolderSyncCommand.Execute(null);
        //}

        //[TestMethod]
        //public void 同期()
        //{
        //    var targetPath = "/Demo/";
        //    var vm = new MyMainVM();
        //    vm.Init();            
        //    vm.SelectedFolder = GetAndEnsureFolderTree(vm, targetPath);
        //    vm.FolderSyncCommand.Execute(null);
        //}

        [TestMethod]
        public void フォルダ移動()
        {
            var targetPath = "/UNITTEST/";
            var vm = new MyMainVM();
            vm.Init();

            var targetFolder = GetAndEnsureFolderTree(vm, targetPath);
            vm.CurrentPath = targetPath;

            vm.SelectedFolder = targetFolder.Folders.Where(x => x.Title == "SUB1").First();
            vm.FolderCopyCommand.Execute(null);

            vm.SelectedFolder = targetFolder.Folders.Where(x => x.Title == "SUB2").First();
            vm.FolderPasteCommand.Execute(null);

            var targetFolder2 = GetAndEnsureFolderTree(vm, targetPath + "SUB2/");
            Assert.IsTrue(targetFolder2.Folders.Any(x => x.Title == "SUB1"));

            vm.SelectedFolder = targetFolder2.Folders.Where(x => x.Title == "SUB1").First();
            vm.FolderCutCommand.Execute(null);

            GetAndEnsureFolderTree(vm, targetPath);
            vm.SelectedFolder = targetFolder.Folders.Where(x => x.Title == "SUB3").First();
            vm.FolderPasteCommand.Execute(null);

            var targetFolder3 = GetAndEnsureFolderTree(vm, targetPath + "SUB3/");
            Assert.IsTrue(targetFolder3.Folders.Any(x => x.Title == "SUB1"));

            vm.SelectedFolder = targetFolder3.Folders.Where(x => x.Title == "SUB1").First();
            vm.FolderDeleteCommand.Execute(null);

        }


        [TestMethod]
        public void パスワード保護_Password()
        {

            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, "protected mode test");
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            var current = GetAndEnsureFolderTree(vm, "/protect mode test/password/");
            vm.SelectedFolder = current;

            vm.DownloadFolderCommand.Execute(work);
            Assert.AreEqual("", vm.Message);

            MsOffCryptoUtil.Decrypto(Path.Combine(work, "重要.xlsx"), "Password$1234");
            MsOffCryptoUtil.Decrypto(Path.Combine(work, "重要.pptx"), "Password$1234");
            Unzip(Path.Combine(work, "重要.txt.zip"), "Password$1234", Path.Combine(work, "Work"));
            PdfDecrypto(Path.Combine(work, "重要.pdf"), "Password$1234");
        }

        [TestMethod]
        public void パスワード保護_UserPassword()
        {
            var userpass = AppUtil.GetAppConfigValue("Password");
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, "protected mode test");
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            var current = GetAndEnsureFolderTree(vm, "/protect mode test/user password/");
            vm.SelectedFolder = current;

            vm.DownloadFolderCommand.Execute(work);
            Assert.AreEqual("", vm.Message);

            MsOffCryptoUtil.Decrypto(Path.Combine(work, "重要.xlsx"), userpass);
            MsOffCryptoUtil.Decrypto(Path.Combine(work, "重要.pptx"), userpass);
            Unzip(Path.Combine(work, "重要.txt.zip"), userpass, Path.Combine(work, "Work"));
            PdfDecrypto(Path.Combine(work, "重要.pdf"), userpass);
        }

        [TestMethod]
        public void パスワード保護_ZipPassword()
        {
            var password = "Password$1234";
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, "protected mode test");
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            var current = GetAndEnsureFolderTree(vm, "/protect mode test/zip password/");
            vm.SelectedFolder = current;

            vm.DownloadFolderCommand.Execute(work);
            Assert.AreEqual("", vm.Message);

            Unzip(Path.Combine(work, "重要.xlsx.zip"), password, Path.Combine(work, "Work"));
            Assert.IsFalse(MsOffCryptoUtil.IsEncryptedPackage(Path.Combine(work, "Work", "重要.xlsx.zip")));
            Unzip(Path.Combine(work, "重要.pptx.zip"), password, Path.Combine(work, "Work"));
            Assert.IsFalse(MsOffCryptoUtil.IsEncryptedPackage(Path.Combine(work, "Work", "重要.pptx.zip")));
            Unzip(Path.Combine(work, "重要.txt.zip"), password, Path.Combine(work, "Work"));
            Unzip(Path.Combine(work, "重要.pdf.zip"), password, Path.Combine(work, "Work"));
        }
        [TestMethod]
        public void パスワード保護_ZipUserPassword()
        {
            var userpass = AppUtil.GetAppConfigValue("Password");
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, "protected mode test");
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            var current = GetAndEnsureFolderTree(vm, "/protect mode test/zip user password/");
            vm.SelectedFolder = current;

            vm.DownloadFolderCommand.Execute(work);
            Assert.AreEqual("", vm.Message);

            Unzip(Path.Combine(work, "重要.xlsx.zip"), userpass, Path.Combine(work, "Work"));
            Assert.IsFalse(MsOffCryptoUtil.IsEncryptedPackage(Path.Combine(work, "Work", "重要.xlsx.zip")));
            Unzip(Path.Combine(work, "重要.pptx.zip"), userpass, Path.Combine(work, "Work"));
            Assert.IsFalse(MsOffCryptoUtil.IsEncryptedPackage(Path.Combine(work, "Work", "重要.pptx.zip")));
            Unzip(Path.Combine(work, "重要.txt.zip"), userpass, Path.Combine(work, "Work"));
            Unzip(Path.Combine(work, "重要.pdf.zip"), userpass, Path.Combine(work, "Work"));
        }

        [TestMethod]
        public void パスワード保護_UserPassword_ZIP()
        {
            var userpass = AppUtil.GetAppConfigValue("Password");
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, "protected mode test");
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            var current = GetAndEnsureFolderTree(vm, "/protect mode test/user password/");
            vm.SelectedFolder = current;

            BlobDataManager.Instance.DownloadAsync(current.Path + "重要.pptx", Path.Combine(work, "重要.pptx.zip"), null, "zip", null, 0).Wait();
            Unzip(Path.Combine(work, "重要.pptx.zip"), userpass, Path.Combine(work, "Work"));
            Assert.IsTrue(MsOffCryptoUtil.IsEncryptedPackage(Path.Combine(work, "Work", "重要.pptx")));

            BlobDataManager.Instance.DownloadAsync(current.Path + "重要.pdf", Path.Combine(work, "重要.pdf.zip"), null, "zip", null, 0).Wait();
            Unzip(Path.Combine(work, "重要.pdf.zip"), userpass, Path.Combine(work, "Work"));
            PdfDecrypto(Path.Combine(work, "Work", "重要.pdf"), userpass);

            BlobDataManager.Instance.DownloadAsync(current.Path + "重要.txt", Path.Combine(work, "重要.txt.zip"), null, "zip", null, 0).Wait();
            Unzip(Path.Combine(work, "重要.txt.zip"), userpass, Path.Combine(work, "Work"));
        }


        [TestMethod]
        public void パスワード保護_ZipPassword_ZIP()
        {
            var password = "Password$1234";
            var vm = new MyMainVM();
            vm.Init();
            var work = Path.Combine(Environment.CurrentDirectory, "protected mode test");
            if (Directory.Exists(work))
            {
                try
                {
                    Directory.Delete(work, true);
                }
                catch (Exception) { }
            }
            Directory.CreateDirectory(work);

            var current = GetAndEnsureFolderTree(vm, "/protect mode test/zip password/");
            vm.SelectedFolder = current;

            BlobDataManager.Instance.DownloadAsync(current.Path + "重要.pptx", Path.Combine(work, "重要.pptx.zip"), null, "zip", null, 0).Wait();
            Unzip(Path.Combine(work, "重要.pptx.zip"), password, Path.Combine(work, "Work"));
            Assert.IsFalse(MsOffCryptoUtil.IsEncryptedPackage(Path.Combine(work, "Work", "重要.pptx")));

            BlobDataManager.Instance.DownloadAsync(current.Path + "重要.pdf", Path.Combine(work, "重要.pdf.zip"), null, "zip", null, 0).Wait();
            Unzip(Path.Combine(work, "重要.pdf.zip"), password, Path.Combine(work, "Work"));
            Assert.IsFalse(PdfCryptoUtil.IsPasswordProtected(Path.Combine(work, "Work", "重要.pdf")));

            BlobDataManager.Instance.DownloadAsync(current.Path + "重要.txt", Path.Combine(work, "重要.txt.zip"), null, "zip", null, 0).Wait();
            Unzip(Path.Combine(work, "重要.txt.zip"), password, Path.Combine(work, "Work"));
        }

        public static void PdfDecrypto(string filePath, string password)
        {
            var outPdf = Path.GetTempFileName();
            try
            {
                using (Stream input = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (Stream output = new FileStream(outPdf, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        iTextSharp.text.pdf.PdfReader tempReader = new iTextSharp.text.pdf.PdfReader(input, new System.Text.ASCIIEncoding().GetBytes(password));
                        PdfStamper stamper = new PdfStamper(tempReader, output);
                        stamper.Close();
                        tempReader.Close();
                    }
                }
                File.Copy(outPdf, filePath, true);
            }
            finally
            {
                File.Delete(outPdf);
            }
        }


    }
}
